package service

import (
	"regexp"
	"strings"
	"unicode/utf8"

	"go-file-perception-model/internal/config"
)

// ChunkUtils 分块工具类
type ChunkUtils struct {
	config *config.FileIndexConfig
}

// NewChunkUtils 创建分块工具类
func NewChunkUtils(cfg *config.FileIndexConfig) *ChunkUtils {
	return &ChunkUtils{
		config: cfg,
	}
}

// MergeChunks 合并两个分块
func (cu *ChunkUtils) MergeChunks(chunk1, chunk2 string, chunk1First bool) string {
	if chunk1First {
		return strings.TrimSpace(chunk1 + " " + chunk2)
	}
	return strings.TrimSpace(chunk2 + " " + chunk1)
}

// GetContentPreview 获取内容预览（用于日志记录）
func (cu *ChunkUtils) GetContentPreview(content string, maxLen int) string {
	cleaned := strings.ReplaceAll(strings.TrimSpace(content), "\n", " ")
	if len(cleaned) <= maxLen {
		return cleaned
	}
	return cleaned[:maxLen] + "..."
}

// AnalyzeChunkType 分析分块类型
func (cu *ChunkUtils) AnalyzeChunkType(chunk string) ChunkType {
	chunk = strings.TrimSpace(chunk)
	
	// 检查是否为数字序列
	if cu.isNumberSequence(chunk) {
		return ChunkTypeNumberSequence
	}
	
	// 检查是否为单独的标点符号
	if cu.isPunctuation(chunk) {
		return ChunkTypePunctuation
	}
	
	// 检查是否为句子片段
	if cu.isFragment(chunk) {
		return ChunkTypeFragment
	}
	
	// 非常短的内容（小于20个字符）
	if len(chunk) <= 20 {
		return ChunkTypeVeryShort
	}
	
	return ChunkTypeNormal
}

// isNumberSequence 检查是否为数字序列
func (cu *ChunkUtils) isNumberSequence(chunk string) bool {
	// 匹配常见的数字序列模式
	patterns := []string{
		`^\d+\.$`,        // "1."
		`^\d+\)$`,        // "1)"
		`^\(\d+\)$`,      // "(1)"
		`^[一-九]+\.$`,   // 中文数字 "一."
		`^[一-九]+、$`,   // 中文数字 "一、"
		`^[a-zA-Z]\.$`,   // "a.", "A."
		`^[a-zA-Z]\)$`,   // "a)", "A)"
		`^\([a-zA-Z]\)$`, // "(a)", "(A)"
		`^[ivxlcdm]+\.$`, // 罗马数字 "i.", "ii."
		`^[IVXLCDM]+\.$`, // 大写罗马数字
	}
	
	for _, pattern := range patterns {
		if matched, _ := regexp.MatchString(pattern, chunk); matched {
			return true
		}
	}
	
	return false
}

// isPunctuation 检查是否为单独的标点符号
func (cu *ChunkUtils) isPunctuation(chunk string) bool {
	// 匹配常见的标点符号
	patterns := []string{
		`^[.,;:!?。，；：！？…]+$`, // 中英文标点
		`^["|"|'|'|"]+$`,           // 引号
		`^[()\[\]{}]+$`,            // 括号
		`^[-—–]+$`,                 // 破折号
	}
	
	for _, pattern := range patterns {
		if matched, _ := regexp.MatchString(pattern, chunk); matched {
			return true
		}
	}
	
	return false
}

// isFragment 检查是否为句子片段
func (cu *ChunkUtils) isFragment(chunk string) bool {
	// 以小写字母开头的可能是句子的后半部分
	if len(chunk) > 0 && chunk[0] >= 'a' && chunk[0] <= 'z' {
		return true
	}
	
	// 以连接词开头的可能是句子的继续
	connectors := []string{"而", "但是", "然而", "因此", "同时", "另外", "and", "but", "however", "therefore", "meanwhile"}
	for _, connector := range connectors {
		if strings.HasPrefix(strings.ToLower(chunk), strings.ToLower(connector)) {
			return true
		}
	}
	
	return false
}

// ValidateUnicodeString 验证Unicode字符串
func (cu *ChunkUtils) ValidateUnicodeString(s string) bool {
	return utf8.ValidString(s)
}

// SplitByCharacterLimit 按字符限制分割（当句子太长时使用）
func (cu *ChunkUtils) SplitByCharacterLimit(text string, maxSize int) []string {
	var chunks []string
	
	for len(text) > maxSize {
		// 找到合适的分割点（空格或标点）
		splitPoint := maxSize
		for i := maxSize - 1; i > maxSize/2 && i < len(text); i-- {
			if text[i] == ' ' || text[i] == '\t' || text[i] == '\n' || 
			   text[i] == ',' || text[i] == '.' || text[i] == ';' {
				splitPoint = i + 1
				break
			}
		}
		
		chunk := strings.TrimSpace(text[:splitPoint])
		if chunk != "" {
			chunks = append(chunks, chunk)
		}
		
		text = strings.TrimSpace(text[splitPoint:])
	}
	
	// 添加剩余部分
	if text != "" {
		chunks = append(chunks, text)
	}
	
	return chunks
}

// CleanSentence 清理句子文本
func (cu *ChunkUtils) CleanSentence(sentence string) string {
	// 去除多余空白
	cleaned := strings.TrimSpace(sentence)
	
	// 规范化空白字符
	cleaned = regexp.MustCompile(`\s+`).ReplaceAllString(cleaned, " ")
	
	return cleaned
}

// CalculateChunkLength 计算分块长度（考虑Unicode字符）
func (cu *ChunkUtils) CalculateChunkLength(chunk string) int {
	return len(strings.TrimSpace(chunk))
}

// IsValidChunk 检查分块是否有效
func (cu *ChunkUtils) IsValidChunk(chunk string) bool {
	cleaned := strings.TrimSpace(chunk)
	return cleaned != "" && cu.ValidateUnicodeString(cleaned)
}

// GetChunkTypeString 获取分块类型字符串表示
func (cu *ChunkUtils) GetChunkTypeString(chunkType ChunkType) string {
	return string(chunkType)
}

// GetMergeReasonString 获取合并原因字符串表示
func (cu *ChunkUtils) GetMergeReasonString(reason ChunkMergeReason) string {
	return string(reason)
}